package com.flka.demo.utils;


import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;


public class SignHelper {
    private static final Log logger = LogFactory.getLog(SignHelper.class);

    /**
     * 报文签名
     * @param formData 代签名参数集合
     * @param securityKey 签名密钥
     * @return 返回签名
     */
    public static String sign(Map<String, String> formData, String securityKey) {
        if (formData == null) {
            throw new IllegalArgumentException("数据不能为空");
        }
        if (formData.isEmpty()) {
            throw new IllegalArgumentException("参与验签的数据不能全部为空");
        }
        if (securityKey == null) {
            throw new IllegalArgumentException("安全校验码数据不能为空");
        }
        String stringToSign = doStringToSign(formData);
        StringBuilder pendingToSign = new StringBuilder();
        pendingToSign.append(stringToSign);
        pendingToSign.append(securityKey);
        String signature = DigestUtils.md5Hex(pendingToSign.toString());
        logger.info("签名结果[" + signature + "]");
        return signature;
    }

    /**
     * 转换成代签字符串
     * @param stringMap 代签名报文
     * @return
     */
    protected static String doStringToSign(Map<String, String> stringMap) {
        String waitToSignStr = null;
        Map<String, String> sortedMap = new TreeMap<>(stringMap);
        if (sortedMap.containsKey("sign")) {
            sortedMap.remove("sign");
        }
        StringBuilder stringToSign = new StringBuilder();
        if (sortedMap.size() > 0) {
            for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
                if (entry.getValue() != null) {
                    stringToSign.append(String.valueOf(entry.getKey())).append("=").append(String.valueOf(entry.getValue())).append("&");
                }
            }
            stringToSign.deleteCharAt(stringToSign.length() - 1);
            waitToSignStr = stringToSign.toString();
            logger.info("代签字符串[" + waitToSignStr + "]");
        }
        return waitToSignStr;
    }


    /**
     *  将收到的平台json报文转换成Map集合后使用此函数进行验签
     * @param formData 收到的原始报文
     * @param securityKey 签名密钥
     * @return
     */
    public static boolean verifySign(Map<String, String> formData , String securityKey) {
        if (formData == null) {
            throw new IllegalArgumentException("数据不能为空");
        }
        if (formData.isEmpty()) {
            throw new IllegalArgumentException("参与验签的数据不能全部为空");
        }
        if (StringUtil.isEmpty(securityKey)) {
            throw new IllegalArgumentException("安全校验码数据不能为空");
        }
        String orgSign = formData.get("sign");
        if(StringUtil.isEmpty(orgSign)) {
            throw new IllegalArgumentException("原始签名不存在,请检查报文");
        }
        String sign = sign(formData , securityKey);
        return StringUtil.equals(sign , orgSign);
    }


}

